<?php
declare (strict_types = 1);

namespace app\command;

use app\api\cache\CarefreeCache;
use app\api\services\CarefreeInfoService;
use app\common\models\Carefree\CarefreeMemberFinance;
use app\common\models\Carefree\CarefreeOrder;
use app\common\models\Carefree\CarefreeProfitPoolLog;
use app\common\models\Carefree\CarefreeRedAmountLog;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;

class Carefree extends Command
{
    protected function configure()
    {
        // 指令配置
        $this->setName('carefree')
            ->setDescription('the carefree command');
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    protected function execute(Input $input, Output $output)
    {
        $output->writeln('开始：'.date('Y-m-d H:i:s'));
        $where = [
            ['score|send_score','>',0],
        ];
        $list = CarefreeMemberFinance::getInstance()->where($where)->select();
        $config = CarefreeCache::getKeyData('carefree','base');
        $randNum = 0;
        if(!empty($config['scope_value'])){
            list($start,$end) = explode('-',$config['scope_value']);
            $randNum = $this->randomFloat($start,$end,4);
        }
        dump('范围内随机数：'.$randNum);
        //今日分红金额 今日分红金额=平台总分红积分*会员分红基数
        $totalScore = CarefreeMemberFinance::getInstance()->sum('score') ?: 0;
        $todayRed = bcmul((string)$totalScore, (string)($config['base_rate']*0.01),4);
        dump('今日分红金额：'.$todayRed);
        $totalPool = CarefreeProfitPoolLog::getInstance()->where('status',1)->sum('amount') ?: 0;
        //总分红池减去已分的红包
        $allRedPacket = CarefreeMemberFinance::getInstance()->sum('all_red_packet');
        $totalPool = bcsub((string)$totalPool, (string)$allRedPacket,4);
        dump('剩余分红池：'.$totalPool);
        $base = 0;
        if($totalPool > 0) {
            $base = bcdiv($todayRed, $totalPool, 4);
        }
        dump('平台分红基数：'.$base);
        foreach($list as $val){
            /*$where = [
                ['user_id','=',$val['userId']],
                ['status','=',1],
                ['create_at','>=',date('Y-m-d')]
            ];
            $count = CarefreeRedAmountLog::getInstance()->where($where)->count();
            if($count > 0){
                dump($val['userId'].'今天已发放');
                continue;
            }
            */
            if($val['sendTime'] >= date('Y-m-d')){
                dump($val['userId'].'今天已发放');
                continue;
            }
            $type = 'send_score';
            $score = $val['send_score'];
            if($val['score'] > 0){
                $score =  $val['score'];
                $type = 'score';
            }
            CarefreeMemberFinance::getInstance()->startTrans();
            try{
                //$baseRate = $val['speed_rate'];
                $baseRate = $config['base_rate'];
                //会员分红基数上限
                $baseRate = min($baseRate,$config['max']);
                $baseRate = bcmul((string)$baseRate, (string)0.01,4);
                if($config['type'] == 0){
                    //个人分红积分*会员分红基数*平台分红基数
                    $mul = $baseRate*$config['quota_value'];
                    $profit = bcmul($score, (string)$mul,4);
                }elseif ($config['type'] == 1){
                    dump('用户ID：'.$val['userId']);
                    dump('当前用户积分：'.$score);
                    dump('随机数：'.$randNum);
                    dump('会员分红基数：'.$baseRate);
                    $mul = $baseRate*$randNum;
                    $profit = bcmul($score, (string)$mul,4);
                }else{
                    //计算今日分红金额-总分红池 是否大于0，大于0表示 平台分红基数直接按1计算，如果小于 平台分红基数则为：今日分红金额/总分红池 保留4位小数
                    $num = bcsub($todayRed, $totalPool,4);
                    $profit = 0;
                    if($num > 0){
                        //个人分红积分*会员分红基数*1
                        $profit = bcmul($score, $baseRate,4);
                    }else{
                        //个人分红积分*会员分红基数*分红基数(今日分红金额/总分红池)
                        if($totalPool > 0){
                            $base = bcdiv($todayRed, (string)$totalPool,4);
                            $mul = $baseRate*$base;
                            $profit = bcmul($score, (string)$mul,4);
                        }
                    }
                }
                if($profit > $score){
                    $profit = $score;
                }

                //返还本金
                //1待发货 2待收货 3已收货 4已完成
                $paybackDay = $config['payback_day'] ?? 0;
                $time = strtotime(date('Y-m-d H:i:s')) - ($paybackDay * 86400);
                $formatTime = date('Y-m-d H:i:s',$time);
                $where = [
                    ['status','in',[1,2,3,4]],
                    ['user_id','=',$val['userId']],
                    ['pay_at','<',$formatTime],
                    ['is_payback','=',0]
                ];
                if(!empty($val['payback_time'])){
                    $where[] = ['pay_at','>',$formatTime];
                }
                $total = CarefreeOrder::getInstance()->where($where)->sum('sell_price') ?: 0;
                if($total > 0 && $paybackDay > 0){
                    CarefreeOrder::getInstance()->where($where)->update(['is_payback' => 1,'payback_time' => date('Y-m-d H:i:s')]);
                    $where = [
                        ['user_id','=',$val['userId']],
                        ['status','=',1],
                    ];
                    if(!empty($val['payback_time'])){
                        $where[] = ['create_at','>',$val['payback_time']];
                    }
                    $redAmount = CarefreeRedAmountLog::getInstance()->where($where)->sum('amount') ?: 0;
                    $payback = bcsub((string)$total, (string)$redAmount,4);
                    if($payback > 0){
                        $msg = '平台分红，获得分红红包' . $payback;
                        CarefreeInfoService::getInstance()->addFinanceLog($val['userId'],'add',$payback,$msg,'',1);
                        $msg = '平台积分分红，消耗分红积分'.$payback;
                        CarefreeInfoService::getInstance()->addFinanceLog($val['userId'],'change',$payback,$msg,'',0);
                    }
                    $val['payback_time'] = date('Y-m-d H:i:s');
                    $val->save();
                }else{
                    $msg = '平台积分分红，消耗分红积分'.$profit;
                    if($type == 'send_score'){
                        CarefreeInfoService::getInstance()->addFinanceLog($val['userId'],'change',0,$msg,'',0,$profit);
                    }else{
                        CarefreeInfoService::getInstance()->addFinanceLog($val['userId'],'change',$profit,$msg,'',0);
                    }

                    $msg = '平台分红，获得分红红包' . $profit;
                    CarefreeInfoService::getInstance()->addFinanceLog($val['userId'],'add',$profit,$msg,'',1);
                }


                $val->send_time = date('Y-m-d H:i:s');
                $val->save();

                //清零
                /*
                if($config['speed_mode'] == 0){
                    $where = [
                        ['user_id','=',$val['userId']],
                        ['status','=',1]
                    ];
                    if(!empty($val['zeroTime'])){
                        $where[] = ['create_at','>',$val['zeroTime']];
                    }
                    $redAmount = CarefreeRedAmountLog::getInstance()->where($where)->sum('amount') ?: 0;
                    //达到分红单位扣减速度
                    if($redAmount >= $config['fy_unit']){
                        $financeData = [
                            'zero_time' => date('Y-m-d H:i:s'),
                        ];
                        $reduce = bcdiv((string)$redAmount,$config['fy_unit']);
                        $reduce = bcmul((string)$reduce, $config['base_rate'],2);
                        //分红金额/1680 * 0.4
                        CarefreeMemberFinance::getInstance()->where('user_id',$val['userId'])->update($financeData);
                        $speedRate = CarefreeMemberFinance::getInstance()->where('user_id',$val['userId'])->value('speed_rate');
                        $userSpeedRate = $speedRate;
                        $speedRate = bcsub($speedRate,$reduce,2);
                        if($speedRate >= $config['base_rate']){
                            $msg = '积分分红达到临界点，扣减速度';
                            CarefreeInfoService::getInstance()->addFinanceLog($val['userId'],'change',$reduce,$msg,'',4);
                        }else{
                            if($userSpeedRate > $config['base_rate']){
                                $reduce = bcsub($userSpeedRate,$config['base_rate'],2);
                                $msg = '积分分红达到临界点，扣减速度';
                                CarefreeInfoService::getInstance()->addFinanceLog($val['userId'],'change',$reduce,$msg,'',4);
                            }
                        }
                    }
                }
                */
                CarefreeMemberFinance::getInstance()->commit();
            }catch (\Exception $e){
                $output->writeln($e->getMessage().$e->getLine());
                Log::error($e->getMessage().$e->getLine());
                CarefreeMemberFinance::getInstance()->rollback();
            }
        }
        $output->writeln('结束：'.date('Y-m-d H:i:s'));
    }

    function randomFloat($min = 0, $max = 1, $decimalPlace = 2): string
    {
        $num = $min + mt_rand() / mt_getrandmax() * ($max - $min);
        //控制小数后几位
        return sprintf("%.{$decimalPlace}f",$num);
    }
}
